
#include "ft6x36.h"

#include "lv_port_indev.h"
#include "lv_port_disp.h"

/************************************************
 * 一、我们在文件"lv_port_indev.c"顶部定义宏定义
 ************************************************/
#define LV_USE_INDEV_TOUCHPAD 	0x1u
#define LV_USE_INDEV_MOUSE	 	0x2u
#define LV_USE_INDEV_KEYPAD 	0x4u
#define LV_USE_INDEV_ENCODER 	0x8u
#define LV_USE_INDEV_BUTTON 	0x10u
#define LV_USE_INDEV  	        LV_USE_INDEV_TOUCHPAD	 
						 			 
/************************************************
 * 二、根据注释 我们找到 STATIC PROTOTYPES，按类型
 * 添加预处理语句
 ************************************************/
#if ( LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD ) == LV_USE_INDEV_TOUCHPAD
static void touchpad_init(void);
static void touchpad_read(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t * data);
// static bool touchpad_is_pressed(void);
// static void touchpad_get_xy(lv_coord_t *x, lv_coord_t *y);

#define LVGL_DISP_SLEEP_TIME    300     // 显示屏睡眠时间/100ms
#define LVGL_DISP_WKUP_DELAY    3       // 唤醒消抖时间

static void touchpad_init(void)
{
    lvgl_i2c_init(CONFIG_LV_I2C_TOUCH_PORT);
    ft6x06_init(FT6236_I2C_SLAVE_ADDR);
}

static void touchpad_read(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t * data)
{
    bool res = false;
    res = ft6x36_read(indev_drv, data);
#if LVGL_VERSION_MAJOR >= 8
    data->continue_reading = res;
#endif

#ifdef LVGL_DISP_SLEEP_TIME
    static uint8_t lv_disp_wakeup_time = 0;  // 唤醒时间
    static uint16_t lv_disp_sleep_time = LVGL_DISP_SLEEP_TIME;  // 单位100ms
    if (data->state == LV_INDEV_STATE_REL) {  // 没有触摸
        if (lv_disp_sleep_time && --lv_disp_sleep_time == 0) {
            lcd_bk_set_brightness(0); // 熄屏
        }
        if (lv_disp_wakeup_time) { lv_disp_wakeup_time = 0; }
    } else {  // 有触摸
        if (lv_disp_sleep_time == 0) {  // 首次唤醒 
            if (++lv_disp_wakeup_time >= LVGL_DISP_WKUP_DELAY) {  // 唤醒消抖
                lcd_bk_set_brightness(CONFIG_DEFAULT_BACKLIGHT);
                lv_disp_sleep_time = LVGL_DISP_SLEEP_TIME;  // 重新装载
            }  
        } else {
            lv_disp_sleep_time = LVGL_DISP_SLEEP_TIME;  // 重新装载
        }
        if (lv_disp_wakeup_time) {  // 唤醒状态，等待松手
            data->state = LV_INDEV_STATE_REL;
        }
    }
#endif
}
#endif

#if ( LV_USE_INDEV & LV_USE_INDEV_MOUSE ) == LV_USE_INDEV_MOUSE
static void mouse_init(void);
static bool mouse_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static bool mouse_is_pressed(void);
static void mouse_get_xy(lv_coord_t * x, lv_coord_t * y);
#endif

#if ( LV_USE_INDEV & LV_USE_INDEV_KEYPAD ) == LV_USE_INDEV_KEYPAD
static void keypad_init(void);
static bool keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static uint32_t keypad_get_key(void);
#endif

#if ( LV_USE_INDEV & LV_USE_INDEV_ENCODER ) == LV_USE_INDEV_ENCODER
static void encoder_init(void);
static bool encoder_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static void encoder_handler(void);
#endif

#if ( LV_USE_INDEV & LV_USE_INDEV_BUTTON ) == LV_USE_INDEV_BUTTON
static void button_init(void);
static bool button_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
static int8_t button_get_pressed_id(void);
static bool button_is_pressed(uint8_t id);
#endif

/************************************************
 * 我们继续往下看是indev的初始化函数实现，官方注释
 * 很贴心，大家看着添加预处理语句就行
 ************************************************/
void lv_port_indev_init(void)
{
    /* Here you will find example implementation of input devices supported by LittelvGL:
     *  - Touchpad
     *  - Mouse (with cursor support)
     *  - Keypad (supports GUI usage only with key)
     *  - Encoder (supports GUI usage only with: left, right, push)
     *  - Button (external buttons to press points on the screen)
     *
     *  The `..._read()` function are only examples.
     *  You should shape them according to your hardware
     */

    static lv_indev_drv_t indev_drv;  // 静态（全生命周期）

#if ( LV_USE_INDEV & LV_USE_INDEV_TOUCHPAD ) == LV_USE_INDEV_TOUCHPAD
    /*------------------
     * Touchpad
     * -----------------*/

    /*Initialize your touchpad if you have*/
    touchpad_init();

    /*Register a touchpad input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = touchpad_read;
    lv_indev_drv_register(&indev_drv);
#endif
#if ( LV_USE_INDEV & LV_USE_INDEV_MOUSE ) == LV_USE_INDEV_MOUSE
    /*------------------
     * Mouse
     * -----------------*/

    /*Initialize your touchpad if you have*/
    mouse_init();

    /*Register a mouse input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = mouse_read;
    indev_mouse = lv_indev_drv_register(&indev_drv);

    /*Set cursor. For simplicity set a HOME symbol now.*/
    lv_obj_t * mouse_cursor = lv_img_create(lv_disp_get_scr_act(NULL), NULL);
    lv_img_set_src(mouse_cursor, LV_SYMBOL_HOME);
    lv_indev_set_cursor(indev_mouse, mouse_cursor);
#endif
#if ( LV_USE_INDEV & LV_USE_INDEV_KEYPAD ) == LV_USE_INDEV_KEYPAD
    /*------------------
     * Keypad
     * -----------------*/

    /*Initialize your keypad or keyboard if you have*/
    keypad_init();

    /*Register a keypad input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_KEYPAD;
    indev_drv.read_cb = keypad_read;
    indev_keypad = lv_indev_drv_register(&indev_drv);

    /* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
     * add objects to the group with `lv_group_add_obj(group, obj)`
     * and assign this input device to group to navigate in it:
     * `lv_indev_set_group(indev_keypad, group);` */
#endif
#if ( LV_USE_INDEV & LV_USE_INDEV_ENCODER ) == LV_USE_INDEV_ENCODER
    /*------------------
     * Encoder
     * -----------------*/

    /*Initialize your encoder if you have*/
    encoder_init();

    /*Register a encoder input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_ENCODER;
    indev_drv.read_cb = encoder_read;
    indev_encoder = lv_indev_drv_register(&indev_drv);

    /* Later you should create group(s) with `lv_group_t * group = lv_group_create()`,
     * add objects to the group with `lv_group_add_obj(group, obj)`
     * and assign this input device to group to navigate in it:
     * `lv_indev_set_group(indev_encoder, group);` */
#endif
#if ( LV_USE_INDEV & LV_USE_INDEV_BUTTON ) == LV_USE_INDEV_BUTTON
    /*------------------
     * Button
     * -----------------*/

    /*Initialize your button if you have*/
    button_init();

    /*Register a button input device*/
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_BUTTON;
    indev_drv.read_cb = button_read;
    indev_button = lv_indev_drv_register(&indev_drv);

    /*Assign buttons to points on the screen*/
    static const lv_point_t btn_points[2] = {
            {10, 10},   /*Button 0 -> x:10; y:10*/
            {40, 100},  /*Button 1 -> x:40; y:100*/
    };
    lv_indev_set_button_points(indev_button, btn_points);
#endif

}
 
